我們把事件發生時要執行的函式運用內建的addEventListener註冊在事件發生的目標上,addEventListner的函式可以傳入一個定義好的event參數,它是這個事件的物件,裡面有許多有用的屬性。
<button id="myButton"></button>
<script>
	const myButton = document.getElementById("myButton");
	myButton.addEventListner("click", function(event){
		console.log(event.target === myButton); // true
		console.log(this === myButton); // true
	});
</script>
前面的文章提過函式裡面有this隱含參數,代表呼叫函式的主體。在 event listener 函式裡,也有this參數,不少人認為這裡的this代表觸發事件的元素,正確來說應該是註冊 event listener 的元素才是。
相信你對於「事件會從發生的元素開始,一直往父層元素浮升上去」這個 event bubbling 的機制應該很熟悉。但是你可能不知道,瀏覽器在處理事件,其實是分二階段進行,一開始會先從 root element 也就是<html>,由上而下的往事件發生的元素前進,到達事件發生元素時,又會沿著相同的路線由下往上朝<html>移動。
後面這一段是我們熟悉的 event bubbling,前面那一段叫做 event capture,瀏覽器在二個階段都有能力可以偵測到事件,設定的方法是addEventListener的第三個參數。
這個參數預設是false,沒有寫的話也會是false,在這個設定中 event listener 就會在 bubbling 階段觸發事件。
反之如果設為true,就會在 capture 的階段觸發事件。
既然在 bubbling 時可以在父層元素接收到子層發生的事件,所以當我們要一次監聽許多個元素,而這些元素上的事件函式又都一樣時,我們不必為每個元素都加上 event listener,只要在它們共同的父層加上 event listener 就可以了。這個時候 event listener 函式裡的 event.target會變成是那個父層元素。